import axios from 'axios'
import qs from 'qs'
import store from '../store'
import {clearSystemInfo} from "./util";
import router from "../router";
import Cookies from "js-cookie";
import VXETable from "vxe-table";

axios.defaults.withCredentials = true


// 拦截重复请求
let pending = {}
const CancelToken = axios.CancelToken
// 请求标识；完成请求后也需要执行删除记录，所以添加此参数避免执行无用操作
const removePending = (key, isRequest = false) => {
    if (pending[key] && isRequest) {
        pending[key]('取消重复请求' + key)
    }
    delete pending[key]
}
/**
 * 由于我们请求用了代理 直接代理到测试服务器 因此请求响应拦截器的config.url是一致的，不需要标识值区分
 * 如果请求拦截器和响应拦截器的config.url不一致，就需要一个标识值用来区分判断
 */
const getRequestIdentify = (config) => {
    const url = config.url
    // 返回url及请求参数 post方法请求参数为config.data  get方法请求参数为config.params
    if (config.method === 'post') {
        return encodeURIComponent(config.url + JSON.stringify(config.data))
    }
    return encodeURIComponent(url + JSON.stringify(config.params))
}


class HttpRequest {
    constructor() {
        this.baseUrl = ''
        this.msg = 'Message'
        this.queue = {}
    }

    getInsideConfig() {
        const config = {
            baseURL: '',
            // baseURL: this.baseUrl,
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
            timeout: 60000  // 请求响应超时时间
        }
        return config
    }

    destroy(url) {
        delete this.queue[url]
        if (!Object.keys(this.queue).length) {
            // Spin.hide()
        }
    }

    interceptors(instance, url) {
        // 请求拦截
        instance.interceptors.request.use(config => {
            if (!config.data || !config.data.allowedRepeat) {
                // console.log("重复请求",config.url)
                const requestData = getRequestIdentify(config)
                removePending(requestData, true)
                // 使用 cancel token 取消请求 参考：http://www.axios-js.com/zh-cn/docs/#%E6%8B%A6%E6%88%AA%E5%99%A8
                config.cancelToken = new CancelToken((c) => {
                    pending[requestData] = c
                })
            } else {
                delete config.data.allowedRepeat
            }


            let adminId = Cookies.get('adminId')
            if (adminId) {
                config.headers.common['userToken'] = adminId || '';
            }

            // 添加全局的loading...
            config.data = qs.stringify(config.data)
            if (!Object.keys(this.queue).length) {
                // Spin.show() // 不建议开启，因为界面不友好
            }
            this.queue[url] = true
            return config
        }, error => {
            return Promise.reject(error)
        })
        // 响应拦截
        instance.interceptors.response.use(res => {
            this.destroy(url)
            res.data = typeof res.data == 'object' && res.data ? res.data : {}
            res.data.status = res.status

            if (!res.data.success) {
                // alert(res.data.msg)
                VXETable.modal.alert({
                    id: 'errorMsg',
                    content: res.data.msg,
                    title: '错误提示',
                    lockView: false,
                    status: 'error',
                    zIndex: 99999
                })
                // if (this.msg == 'Message') {
                //     Modal.warning({title:res.data.msg,onOk(){}})
                //     // Message.error(res.data.msg)
                // } else if (this.msg == 'warning') {
                //     Modal.warning({title:res.data.msg,onOk(){}})
                //     // Modal.warning({title: res.data.msg})
                // }

                if (res.data.code == "100012") {
                    // 用户登录失效
                    // console.log(res,111111111)
                    clearSystemInfo()  // 清空路由用户信息
                    // eslint-disable-next-line no-undef
                    store.dispatch('handleLogOut')
                    router.push({
                        name: 'login'
                    })
                    return
                }

                if (res.data.code == '100039') {
                    // 用户距离上次修改密码时间过长或者是管理员修改密码
                    router.push('/pwd-edit')
                    // return
                }

                return Promise.reject(res.data)

            } else {
                return res.data
            }
        }, error => {
            this.destroy(url)
            return Promise.reject(error)
        })
    }

    request(options) {
        const instance = axios.create()
        options = Object.assign(this.getInsideConfig(), options)
        this.msg = options.msgType || 'Message'
        this.interceptors(instance, options.url)
        return instance(options)
    }
}


export default HttpRequest






